// struct enum类型的转换，实现From和Into traits
// 如果A能转换为B，那么B就能转换为A

// From trait
// 实现From trait的类型，可以从其他类型转换为该类型
// 语法：impl From<OtherType> for SelfType { fn from(other: OtherType) -> SelfType { /*... */ } }
use std::convert::From;

// -- from i32 to Number --
#[derive(Debug)]
struct Number {
    value: i32,
}

// 好奇怪 From 和 Into 不能同时共存
/**
 * 应该始终优先实现 From 而不是 Into，因为实现 From 后会自动通过标准库中的通用实现提供对应 Into 的实现。
 * 为泛型函数指定 trait 约束时，优先使用 Into 而不是 From，这样对于只实现了 Into 而没有实现 From 的类型也可以作为参数来使用。
 */
impl From<i32> for Number {
    fn from(item: i32) -> Self {
        Number { value: item }
    }
}

// Into trait
// 实现Into trait的类型，可以将该类型转换为其他类型
use std::convert::Into;

impl Into<Number> for i32 {
    fn into(self) -> Number {
        Number { value: self }
    }
}

fn main() {
    println!("From trait ...");
    // let num = Number::from(30);
    // println!("My number is {:?}", num);

    println!("Into trait ...");
    let int = 5;
    // Try removing the type annotation
    let num: Number = int.into();
    println!("My number is {:?}", num);
}

